use std::borrow::Borrow;
use std::fmt::{Display, Formatter};

use serde::{Deserialize, Serialize};
use snafu::{ResultExt, Snafu};
use url::{ParseError, Url};

/// 资源包链接模板
///
/// 资源包链接模板资源包的名字可以组成下载资源包需要使用的基本链接
#[derive(Deserialize, Serialize, Eq, PartialEq, Debug, Clone)]
#[serde(transparent)]
pub struct ResourceUrl(String);

#[derive(Debug, Snafu)]
pub enum Error {
    #[snafu(display("Failed to parse from string: {s}. -> {source}"))]
    Parse { s: String, source: ParseError },
}

impl Display for ResourceUrl {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}", self.0)
    }
}

impl ResourceUrl {
    pub fn new(s: impl Borrow<str>) -> Result<Self, Error> {
        let s = s.borrow();
        Url::parse(s)
            .map(|_| ResourceUrl(s.to_string()))
            .context(ParseSnafu { s: s.to_string() })
    }
}

impl From<ResourceUrl> for String {
    fn from(value: ResourceUrl) -> Self {
        value.0
    }
}
